

/**
 * 
 * @param {Creep} creep
 * @param {Set} group 
 */
function findConnected(creep, group=new Set([creep])){
    if(group.has(creep.name)){
        return group;
    }
    let nearCreeps=creep.pos.findInRange(FIND_MY_CREEPS, 1);
    for(let nearCreep of nearCreeps){
        group.add(nearCreep);
    }
    return group;
}
/**
 * 
 * @param {Creep[]} creeps 
 */
function markCreeps(creeps){
    for(let creep of creeps){
        creep.near=new Set();
    }

    for(let i=0; i<creeps.length; i++){
        let creepA=creeps[i];
        for(let j=i+1; i<creeps.length; j++){
            let creepB=creeps[j];

            if(creepA.near.has(creepB) && creepB.near.has(creepA)){
                continue;
            }

            creepA.near.add(creepB);
            creepB.near.add(creepA);
        }
    }
}
function average(creep, targetCreep, rate, totalRate){

}
export const jobShare={
    run(_creep){
        console.log('err: share is not runable with one creep');
        return ERR_INVALID_TARGET;
    },
    /**
     * 
     * @param {Creep[]} creeps
     * @param {boolean} isGrouped 
     */
    share(creeps, isGrouped=false){
        if(isGrouped){
            this.groupedShare(creeps);
            return;
        }
        let groups=this.group(creeps);
        for(let group of groups){
            this.groupedShare(group);
        }
    },
    /**
     * 
     * @param {Creep[]} creeps 
     * @returns {Set<Creep>[]}
     */
    group(creeps){
        let creepSet=new Set();
        
        let groups=[];
        markCreeps(creeps);
        creeps=new Set(creeps);

        for(let creep of creeps){
            if(creepSet.has(creep.name)){
                continue;
            }
            let group=findConnected(creep);
            groups.push(group);
            for(let creep of group){
                creepSet.add(creep);
            }
        }
        return groups;
    },
    /**
     * like `share()` but assuming that all creeps in `group` are connected
     * @param {Set<Creep>} group 
     */
    groupedShare(group){
        for(let i=group.values().next(); !i.done; i=i.next()){
            for(let j=i.next(); !j.done; j=j.next()){
                let creepA=i.value;
                let creepB=j.value;

                let energyA=creepA.store[RESOURCE_ENERGY];
                let energyB=creepB.store[RESOURCE_ENERGY];
                let capacityA=creepA.store.getCapacity();
                let capacityB=creepB.store.getCapacity();

                let rateA=energyA/capacityA;
                let rateB=energyB/capacityB;
                let totalEnergy=energyA+energyB;
                let totalCapacity=capacityA+capacityB;

                let totalRate=totalEnergy/totalCapacity;
                let transferEnergy=Math.abs((totalRate-rateA)*capacityA);
                // {
                //     if(rateA<rateB){
                        
                //         creepA.transfer(ener)
                //     }else if(rateA>rateB){

                //     }
                // }

                if(rateA<rateB){
                    let tmp=creepA;
                    creepA=creepB;
                    creepB=tmp;
                }
                creepA.transfer(creepB, RESOURCE_ENERGY,transferEnergy);
            }
        }
        return;
        let medium=0;
        for(let creep of group){
            medium+=creep.store[RESOURCE_ENERGY];

        }
        medium/=group.size;
        medium=Math.floor(medium);

        let small=[];
        let great=[];
        let equal=[];
        for(let creep of group){
            if(creep.store[RESOURCE_ENERGY]<medium){
                small.push(creep);
                creep.energyInGroup='snall';
            }else if(creep.store[RESOURCE_ENERGY]>medium){
                great.push(creep);
                creep.energyInGroup='great';
            }else{
                equal.push(creep);
                creep.energyInGroup='equal';
            }
        }

        for(let creep of group){
            this.transfer(small, great, equal, creep);
        }
    },
    transfer(small, great, equal, creep){
            // if()
            for(let demander of small){
                for(let nearCreep of creep.near){

                }

                let ret=creep.transfer(demander, RESOURCE_ENERGY, 
                    supplier.store[RESOURCE_ENERGY]-medium);
                if(ret == OK){
                    break;
                }
            }
    }
}